package org.zoomdev.zoom.dao.structs.impl;

import org.apache.commons.lang3.StringUtils;
import org.zoomdev.zoom.dao.Dao;
import org.zoomdev.zoom.dao.Record;
import org.zoomdev.zoom.dao.Select;
import org.zoomdev.zoom.dao.impl.SimpleSelect;
import org.zoomdev.zoom.dao.structs.ColumnMeta;
import org.zoomdev.zoom.dao.structs.TableMeta;
import org.zoomdev.zoom.dao.utils.DaoUtils;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class H2DatabaseStruct extends BaseDatabaseStruct {

    public H2DatabaseStruct(Dao dao, String name) {
        super(dao, name);
    }

    protected Select getAllColumns(SimpleSelect ar) {
        ar.clear();
        return ar.from("information_schema.columns")
                .select("TABLE_NAME,COLUMN_NAME,IS_NULLABLE,DATA_TYPE,SEQUENCE_NAME,CHARACTER_MAXIMUM_LENGTH,REMARKS,COLUMN_DEFAULT")
                .where("TABLE_SCHEMA", "PUBLIC");
    }

    protected Select getAllIndexes(SimpleSelect ar) {
        ar.clear();
        return ar.from("INFORMATION_SCHEMA.indexes")
                .select("TABLE_NAME,COLUMN_NAME,INDEX_TYPE_NAME");
    }


    @Override
    protected TableMeta fill(TableMeta meta, Connection connection, SimpleSelect select) throws SQLException {
        getAllColumns(select).where("TABLE_NAME", meta.getName().toUpperCase());
        // columns
        List<Record> list = DaoUtils.query(connection, DaoUtils.recordListParser, select.buildSelect(), select.getArgs());

        getAllIndexes(select).where("TABLE_NAME", meta.getName().toUpperCase());
        //index
        List<Record> indexes = DaoUtils.query(connection, DaoUtils.recordListParser, select.buildSelect(), select.getArgs());
        Map<String, String> indexesMap = getIndexesMap(indexes);

        for (Record record : list) {
            String column = record.getString("columnName");
            ColumnMeta columnMeta = meta.getColumn(column);
            if (columnMeta == null) {
                // 没有？不可能
                log.warn("找不到对应的字段:" + column);
                continue;
            }
            fill(columnMeta, record, indexesMap);
        }

        return meta;
    }

    protected void fill(ColumnMeta columnMeta, Record record, Map<String, String> indexesMap) {
        columnMeta.setName(record.getString("columnName"));
        // columnMeta.setComment(record.getString("remarks"));
        // 常用的
        columnMeta.setAutoIncrement(!StringUtils.isEmpty(record.getString("sequenceName")));
        String keyType = indexesMap.get(getRecordKey(record));
        if (StringUtils.startsWith(keyType, "PRIMARY")) {
            columnMeta.setKeyType(ColumnMeta.KeyType.PRIMARY);
        } else if (StringUtils.startsWith(keyType, "UNIQUE")) {
            columnMeta.setKeyType(ColumnMeta.KeyType.UNIQUE);
        }

//        columnMeta.setDefaultValue(record.getString("columnDefault"));
//        columnMeta.setNullable(record.getString("isNullable").equals("YES"));
//
//        columnMeta.setMaxLength(record.getInt("characterMaximumLength"));
//        columnMeta.setRawType(record.getString("dataType"));


    }

    private Map<String, String> getIndexesMap(List<Record> consts) {
        Map<String, String> keyTypes = new HashMap<String, String>();
        for (Record record : consts) {
            String keyType = record.getString("indexTypeName");
            keyTypes.put(getRecordKey(record), keyType);
        }
        return keyTypes;
    }

    private String getRecordKey(Record record) {
        return record.getString("tableName") +
                record.getString("columnName");
    }
}
